package com.wdb.common.util;

import org.joda.time.DateTime;
import org.joda.time.Days;

import java.util.Date;

public class DateTimeUtils {

    public static final long SECOND = 1000; // 1秒 java已毫秒为单位

    public static final long MINUTE = SECOND * 60; // 一分钟

    public static final long HOUR = MINUTE * 60; // 一小时

    public static final long DAY = HOUR * 24; // 一天

    public static final long WEEK = DAY * 7; // 一周

    public static final long YEAR = DAY * 365; // 一年

    public static final String FORMAT_TIME = "yyyy-MM-dd HH:mm:ss"; // 默认时间格式

    public static final String FORMAT_TIME_MINUTE = "yyyy-MM-dd HH:mm"; // 默认时间格式

    public static final String FORMAT_DAY = "yyyy-MM-dd"; // 默认日期格式

    public static final String FORMAT_MOUTH = "yyyy-MM"; //年-月

    public static final String FORMAT_MOUTH_DAY = "MM.dd"; // 月.日

    /**
     * 获取 yyyy-MM-dd 格式时间
     */
    public static String getYmd(Date date) {
        DateTime nowTime = new DateTime(date);
        return nowTime.toString(FORMAT_DAY);
    }

    /**
     * 获取 MM.dd 格式时间
     */
    public static String getMd(Date date) {
        DateTime nowTime = new DateTime(date);
        return nowTime.toString(FORMAT_MOUTH_DAY);
    }

    /**
     * 获取 yyyy-MM 格式时间
     */
    public static String getYm(Date date) {
        DateTime nowTime = new DateTime(date);
        return nowTime.toString(FORMAT_MOUTH);
    }

    /**
     * 获取当日开始时间
     */
    public static Date getStartOfDay() {
        DateTime nowTime = new DateTime();
        return nowTime.withTimeAtStartOfDay().toDate();
    }

    /**
     * 获取指定日期的开始时间
     */
    public static Date getStartOfDay(Date date) {
        DateTime nowTime = new DateTime(date);
        return nowTime.withTimeAtStartOfDay().toDate();
    }

    /**
     * 获取当日结束时间
     */
    public static Date getEndOfDay() {
        DateTime nowTime = new DateTime();
        return nowTime.millisOfDay().withMaximumValue().toDate();
    }

    /**
     * 计算两个时间相差多少天
     *
     * @param startDate 开始时间
     * @param endDate 结束时间
     */
    public static Integer diffDay(Date startDate, Date endDate) {
        if (startDate == null || endDate == null) {
            return null;
        }
        DateTime dt1 = new DateTime(startDate);
        DateTime dt2 = new DateTime(endDate);
        int day = Days.daysBetween(dt1, dt2).getDays();
        return Math.abs(day);
    }

    /**
     * 根据当前时间减去传入的天数计算日期
     *
     * @param day 天数
     */
    public static Date subtractDay(Integer day) {
        DateTime nowTime = new DateTime();
        return nowTime.plusDays(-day).toDate();
    }

    /**
     * 根据当前周减去传入的周数计算日期
     *
     * @param week 天数
     */
    public static int subtractWeek(Integer week) {
        DateTime nowTime = new DateTime();
        return nowTime.plusWeeks(-week).getWeekOfWeekyear();
    }

    /**
     * 根据当前时间减去传入的月数计算日期
     *
     * @param month 天数
     */
    public static Date subtractMonth(Integer month) {
        DateTime nowTime = new DateTime();
        return nowTime.plusMonths(-month).toDate();
    }

    /**
     * 获取指定时间所在周的开始时间
     */
    public static Date weekStartTime(Date date) {
        DateTime nowTime = new DateTime(date);
        return nowTime.withDayOfWeek(1)
            .withHourOfDay(0)
            .withMinuteOfHour(0)
            .withSecondOfMinute(0)
            .toDate();
    }

    /**
     * 获取指定时间所在周的结束时间
     */
    public static Date weekEndTime(Date date) {
        DateTime nowTime = new DateTime(date);
        return nowTime.withDayOfWeek(7)
            .withHourOfDay(23)
            .withMinuteOfHour(59)
            .withSecondOfMinute(59)
            .toDate();
    }

    /**
     * 获取指定时间所在周的开始时间
     */
    public static Date monthStartTime(Date date) {
        DateTime nowTime = new DateTime(date);
        return nowTime.dayOfMonth()
            .withMinimumValue()
            .withHourOfDay(0)
            .withMinuteOfHour(0)
            .withSecondOfMinute(0)
            .plusMonths(-1)
            .toDate();
    }

    /**
     * 获取指定时间所在月的结束时间
     */
    public static Date monthEndTime(Date date) {
        return new DateTime(date)
            .dayOfMonth()
            .withMaximumValue()
            .withHourOfDay(23)
            .withMinuteOfHour(59)
            .withSecondOfMinute(59)
            .toDate();
    }

    /**
     * 获取12天之前的时间
     */
    public static Date twelveDayBefore() {
        return new DateTime()
            .plusDays(-12)
            .toDate();
    }

    /**
     * 获取12周之前的时间
     */
    public static Date twelveWeekBefore() {
        return new DateTime()
            .withDayOfWeek(1)
            .plusWeeks(-12)
            .toDate();
    }

    /**
     * 获取12月之前的时间
     */
    public static Date twelveMonthBefore() {
        return new DateTime()
            .plusYears(-1)
            .toDate();
    }

    /**
     * 获取当前时间的下一个自然月1号0点整
     */
    public static Date nextMonthFirst(Date date) {
        return new DateTime(date)
            .dayOfMonth()
            .withMinimumValue()
            .plusMonths(1)
            .withHourOfDay(0)
            .withMinuteOfHour(0)
            .withSecondOfMinute(0)
            .withMillisOfSecond(0)
            .toDate();
    }

    /**
     * 获取当前时间的下一个自然月15号0点整
     */
    public static Date nextFifteenDay(Date date) {
        return new DateTime(date)
            .dayOfMonth()
            .withMinimumValue()
            .plusMonths(1)
            .withHourOfDay(0)
            .plusDays(14)
            .withMinuteOfHour(0)
            .withSecondOfMinute(0)
            .withMillisOfSecond(0)
            .toDate();
    }

    /**
     * 获取当前时间的下一个小时整点
     */
    public static Date nextHourFirst(Date date) {
        return new DateTime(date)
            .plusHours(1)
            .withMinuteOfHour(0)
            .withSecondOfMinute(0)
            .withMillisOfSecond(0)
            .toDate();
    }

    /**
     * 获取当前时间的下一个小时的半小时
     */
    public static Date nextHalfHour(Date date) {
        return new DateTime(date)
            .plusHours(1)
            .withMinuteOfHour(0)
            .plusMinutes(30)
            .withSecondOfMinute(0)
            .withMillisOfSecond(0)
            .toDate();
    }
}
